#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <assert.h>

void printHostent(struct hostent *hostinfo) {
    printf("Host name: %s\n", hostinfo->h_name);
    printf("address type: %d\n", hostinfo->h_addrtype);
    printf("address length: %d\n", hostinfo->h_length);
    for (int i = 0; hostinfo->h_aliases[i] != nullptr && hostinfo->h_aliases[i][0] != 0; i++) {
        if (i == 0) printf("host has aliases:\n");
        printf("\t%s\n", hostinfo->h_aliases[i]);
    }
    for (int i = 0; hostinfo->h_addr_list[i] != nullptr && hostinfo->h_addr_list[i][0] != 0; i++) {
        if (i == 0) printf("host has addresses:\n");
        printf("\t%s\n", hostinfo->h_addr_list[i]);
    }
}

int main(int argc, char **argv) {
    assert(argc == 2);
    char *hostname = argv[1];
    struct hostent *hostinfo = gethostbyname(hostname);
    assert(hostinfo);
    printHostent(hostinfo);
    
    struct servent *servinfo = getservbyname("daytime", "tcp");
    assert(servinfo);
    printf("daytime service port is %d\n", ntohs(servinfo->s_port));

    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_port = servinfo->s_port;
    address.sin_addr = *(struct in_addr*)*hostinfo->h_addr_list;

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    int result = connect(sockfd, (struct sockaddr*)&address, sizeof(address));
    assert(result != -1);

    char buffer[1024];
    result = read(sockfd, buffer, sizeof(buffer));
    assert(result > 0);
    buffer[result] = 0;
    printf("the daytime is: %s", buffer);
    close(sockfd);
    return 0;
}